前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
  • 基础篇

    • 环境搭建
    • node部署
    • 基础应用
  • 内置模块

    • 1.0 本地路径处理 path
    • 2.0 文件系统操作 fs
    • 3.1 基础调试 console
    • 3.2 本地调试远程服务器上的Node代码
    • 4.1 网络服务 http
    • 4.2 网络服务 http res
    • 4.3 网络服务 http req
    • 4.4 网络服务 http server
    • 4.5 网络服务 http client
    • 4.6 网络服务 https
    • 4.7 网络TCP net
    • 4.8 网络UDP dgram
    • 4.9 域名解析 dns
    • 5.0 网络地址解析 url
    • 5.1 URL查询字符串 querystring
    • 6.1 流操作 stream
    • 6.2 逐行读取 readline
    • 7.1 进程相关 process
    • 7.2 子进程 child
    • 8.1 二进制数据 buffer
    • 8.2 二进制解码 string_decoder
    • 9.1 事件机制 events
    • 9.2 实用工具模块 util
    • 9.3 数据加密 crypto
    • 9.4 MD5入门介绍及crypto模块的应用
    • 9.4 资源压缩 zlib
    • 9.5 集群 cluster
    • 9.6 v8
  • 进阶篇

    • 5分钟入门非对称加密用法
    • cluster
    • cookie_parser深入
    • crypto模块之理论篇
    • express+cookie_parser签名机制深入剖析
    • express+session实现简易身份认证
    • https
    • log4js入门实例
    • node8_napi
    • 使用 async 控制并发
    • 使用 eventproxy 控制并发
    • 使用 superagent 与 cheerio 完成简单爬虫
    • 基于express+muter的文件上传
    • 将图片转成datauri嵌入到html
    • 常用中间件 body_parser 实现解析
    • 日志模块morgan
    • 服务端字符编解码&乱码处理 charset_enc_dec
    • 测试用例mocha,should,istanbul
    • 调试日志打印debug模块
  • Express

    • 1.1 Express概览篇
    • 1.2 Express
  • Koa2

    • 1.0 koa2概览篇
    • 1.1 快速开始
    • 1.2 async await使用
    • 1.3 koa2简析结构
    • 1.4 koa中间件开发与使用
    • 10.1 单元测试
    • 11.1 开发debug
    • 12.1 快速启动
    • 12.2 框架设计
    • 12.3 分层操作
    • 12.4 数据库设计
    • 12.5 路由设计
    • 12.6 webpack4环境搭建
    • 12.7 使用react
    • 12.8 登录注册功能实现
    • 12.9 session登录态判断处理
    • 13.1 import export使用
    • 2.1 原生koa2实现路由
    • 2.2 koa router中间
    • 3.1 GET请求数据获取
    • 3.2 POST请求数据获取
    • 3.3 koa bodyparser中间件
    • 4.1 原生koa2实现静态资源服务器
    • 4.2 koa static中间件
    • 5.1 koa2使用cookie
    • 5.2 koa2实现session
    • 6.1 koa2加载模板引擎
    • 6.2 ejs模板引擎
    • 7.1 busboy模块
    • 7.2 上传文件简单实现
    • 7.3 异步上传图片实现
    • 8.1 mysql模块
    • 8.2 async await封装使用mysql
    • 8.3 项目建表初始化
    • 9.1 原生koa2实现JSONP
    • 9.2 koa jsonp中间件
  • 其他

    • 操作数据库
    • Session 与 Token
    • Cookie、Session、Token、JWT
    • Socket

# 进程相关 process

30 秒速记

  • process 是全局对象,代表「当前这个 Node 进程」:参数、环境变量、工作目录、输入输出、退出、信号、资源占用都在它上面
  • 退出优先 process.exitCode = 1,让进程自然结束;process.exit() 是硬退出,可能截断还没写完的 stdout
  • uncaughtException / unhandledRejection 只用来记日志然后退出,别吞掉继续跑,交给 PM2、容器去重启
  • 监听了 SIGTERM 就接管了默认退出,清理完要自己退出,还要设个超时兜底
  • 配置在启动时集中从 process.env / process.argv 读一次,业务代码别到处读

process 是 Node.js 里代表当前进程的全局对象,程序和操作系统打交道基本都经过它。 拿参数用 argv,拿配置用 env,读写终端用 stdin / stdout,退出和信号也在这。工程上最容易出问题的是退出:我一般设 process.exitCode 让程序自然退出,而不是到处 process.exit(),后者会直接掐断还没写完的输出。还有部署时容器发 SIGTERM,要监听它做优雅关闭:

process.on('SIGTERM', () => {
  server.close(() => process.exit(0));      // 不再接新请求,处理完存量再退
  setTimeout(() => process.exit(1), 10000).unref(); // 10 秒还没关完就强退
});
@前端进阶之旅: 代码已经复制到剪贴板

理解「进程相关 process」时,要先明确输入、运行阶段和可观察输出。这里的交互实验会分别执行正常路径与失败路径,并把 Node.js 的关键状态变化和同屏代码对应起来;不能只记命令名称。

工程中还要验证退出码、资源清理和异常输入。属于 process 场景的配置应保持最小可复现,并在开发环境与 CI 中使用相同命令复跑,避免把平台差异或隐式默认值带到线上。

process 上的东西多,按用途记会清楚很多:

  • 输入:process.argv(命令行参数)、process.execArgv(Node 自身参数)、process.env(环境变量)、process.stdin。
  • 输出:process.stdout、process.stderr、process.exitCode。
  • 环境:process.cwd()、process.platform、process.version、process.pid。
  • 生命周期:process.exit()、process.on('exit')、process.on('SIGTERM')、process.on('uncaughtException')、process.on('unhandledRejection')。
  • 调度:process.nextTick()。
  • 资源:process.memoryUsage()、process.cpuUsage()、process.uptime()、process.hrtime.bigint()。

有一点常被忽略:exit 事件的回调里只能做同步操作,异步的写日志、发请求不会执行完。要在退出前做异步清理,得在 SIGTERM 或业务结束的地方做,做完再退出。

process.on('exit', (code) => {
  console.log('退出码', code);         // 会打印
  setTimeout(() => console.log('x'), 0); // 永远不会执行
});
process.exitCode = 2;
@前端进阶之旅: 代码已经复制到剪贴板

面试官追问

追问 1命令行工具打印了「完成」,CI 却判它失败,为什么?
参考回答

CI 看的是退出码,不看打印内容。多半是某条路径设了非零 exitCode,或者有未处理的 Promise 拒绝,Node 15 起默认会让进程以非零码退出。echo $? 一看就知道。

追问 2process.exitCode = 1 和 process.exit(1) 有什么区别?
参考回答

前者只是记下退出码,等事件循环空了自然退出,日志、文件写入都能完成;后者立刻退出,挂起的异步操作全丢。脚本里除非确实要马上停,否则用前者。

追问 3代码里加了 process.on('uncaughtException'),打个日志就继续跑,可以吗?
参考回答

不推荐。抛到这里说明某个流程中途崩了,内存里的状态可能已经是乱的,比如锁没释放、连接一半。记完日志就退出,让 PM2 或容器重启一个干净的进程。

追问 4容器发版时总有一批请求报错,和 process 有什么关系?
参考回答

容器停止时先发 SIGTERM,没处理的话进程立刻退出,正在处理的请求就断了。监听 SIGTERM,先 server.close() 停止接新请求,等存量处理完再退,设个超时防止卡死。

追问 5任务报完错一直不退出,可能是什么原因?
参考回答

事件循环里还有东西撑着:没清的 setInterval、没关的数据库连接、没关的 readline。可以用 why-is-node-running 这类工具看是哪个句柄,修好清理逻辑,别靠 process.exit() 硬掐。

# 模块概览

30 秒速记

  • process 是全局对象,不用 require 就能用;require('process') 拿到的是同一个对象
  • 读:命令行参数、环境变量、工作目录、进程 ID、内存占用
  • 写:设环境变量、改工作目录、设退出码、改进程标题
  • 它是进程边界,不是业务全局变量仓库,别往上挂业务状态
  • 配置在启动层集中读一次、校验好,再传给业务模块

process 是 Node.js 的全局对象,用来读写当前进程的信息,不用引入就能直接用。 能读的有命令行参数 argv、环境变量 env、工作目录 cwd()、进程号 pid;能改的有环境变量、工作目录、退出码、进程标题。我的习惯是只在启动入口读 process.env 和 process.argv,整理成一个校验过的 config 对象传下去,业务代码里不直接读,这样测试时换配置很方便,也不会出现十几个地方各自给默认值的情况。

process是node的全局模块,作用比较直观。可以通过它来获得node进程相关的信息,比如运行node程序时的命令行参数。或者设置进程相关信息,比如设置环境变量。

面试官追问

追问 1require('process') 和直接用 process 有区别吗?
参考回答

没区别,拿到的是同一个对象。显式引入的好处是依赖写得清楚,ESM 里也常写 import process from 'node:process'。

追问 2业务模块里到处 process.env.XXX,有什么问题?
参考回答

默认值散落各处,同一个配置不同地方可能给不同的默认值;测试要改环境变量才能换配置。启动时集中读、转类型、校验,导出一个 config 对象,业务只用它。

追问 3把用户会话、缓存挂在 process 上当全局变量用,行不行?
参考回答

别这么干。process 是进程本身的接口,挂上去的东西没有边界、谁都能改,测试也没法隔离。要共享状态就用模块导出的单例。

追问 4服务连到了错误的数据库,代码没报错,怎么用 process 定位?
参考回答

启动时打一行脱敏后的最终配置及来源,比如数据库主机来自 env 还是 argv 覆盖。重点核对 process.env 里实际拿到的值,密码这类字段只打是否存在,不打明文。

# 环境变量:process.env

30 秒速记

  • process.env 是个对象,存当前进程拿到的环境变量,值永远是字符串
  • NODE_ENV=production node env.js 只对这一条命令生效,例子输出应该是「生产环境」
  • 这种 VAR=x cmd 写法 Windows 的 cmd 不认,跨平台用 cross-env
  • 数字、布尔要自己转:process.env.PORT 是 '3000','false' 也是真值
  • 密钥通过环境变量注入可以,但别把整个 process.env 打进日志

process.env 就是当前进程拿到的环境变量,最常见的用法是读 NODE_ENV 判断是不是生产环境。 执行 NODE_ENV=production node env.js,process.env.NODE_ENV 就是 'production',例子会打印「生产环境」。坑主要有三个:值全是字符串,'false' 也是真值,PORT 要 Number() 转;Windows 的 cmd 不认这种前缀写法,团队里有人用 Windows 就上 cross-env;环境变量是启动时继承来的,在终端里 export 不会影响已经跑起来的进程。

const port = Number(process.env.PORT ?? 3000);
const debug = process.env.DEBUG === 'true'; // 别写 Boolean(process.env.DEBUG)
if (Number.isNaN(port)) throw new Error('PORT 必须是数字'); // 启动时就失败
@前端进阶之旅: 代码已经复制到剪贴板

使用频率很高,node服务运行时,时常会判断当前服务运行的环境,如下所示

if(process.env.NODE_ENV === 'production'){
    console.log('生产环境'
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
  • 基础篇

    • 环境搭建
    • node部署
    • 基础应用
  • 内置模块

    • 1.0 本地路径处理 path
    • 2.0 文件系统操作 fs
    • 3.1 基础调试 console
    • 3.2 本地调试远程服务器上的Node代码
    • 4.1 网络服务 http
    • 4.2 网络服务 http res
    • 4.3 网络服务 http req
    • 4.4 网络服务 http server
    • 4.5 网络服务 http client
    • 4.6 网络服务 https
    • 4.7 网络TCP net
    • 4.8 网络UDP dgram
    • 4.9 域名解析 dns
    • 5.0 网络地址解析 url
    • 5.1 URL查询字符串 querystring
    • 6.1 流操作 stream
    • 6.2 逐行读取 readline
    • 7.1 进程相关 process
      • 模块概览
      • 环境变量:process.env
      • 异步:process.nextTick(fn)
      • 获取命令行参数:process.argv
      • 获取node specific参数:process.execArgv
      • 当前工作路径:process.cwd() vs process.chdir(directory)
      • IPC相关
      • 其他
      • 标准输入/标准输出/标准错误输出:process.stdin、process.stdout
      • 用户组/用户 相关
      • 当前进程信息
      • 运行情况/资源占用情况
      • node可执行程序相关信息
      • 进程运行所在环境
      • 警告信息:process.emitWarning(warning);
      • 向进程发送信号:process.kill(pid, signal)
      • 终止进程:process.exit([exitCode])、process.exitCode
      • 事件
      • TODO 待进一步验证
      • 相关链接
    • 7.2 子进程 child
    • 8.1 二进制数据 buffer
    • 8.2 二进制解码 string_decoder
    • 9.1 事件机制 events
    • 9.2 实用工具模块 util
    • 9.3 数据加密 crypto
    • 9.4 MD5入门介绍及crypto模块的应用
    • 9.4 资源压缩 zlib
    • 9.5 集群 cluster
    • 9.6 v8
  • 进阶篇

    • 5分钟入门非对称加密用法
    • cluster
    • cookie_parser深入
    • crypto模块之理论篇
    • express+cookie_parser签名机制深入剖析
    • express+session实现简易身份认证
    • https
    • log4js入门实例
    • node8_napi
    • 使用 async 控制并发
    • 使用 eventproxy 控制并发
    • 使用 superagent 与 cheerio 完成简单爬虫
    • 基于express+muter的文件上传
    • 将图片转成datauri嵌入到html
    • 常用中间件 body_parser 实现解析
    • 日志模块morgan
    • 服务端字符编解码&乱码处理 charset_enc_dec
    • 测试用例mocha,should,istanbul
    • 调试日志打印debug模块
  • Express

    • 1.1 Express概览篇
    • 1.2 Express
  • Koa2

    • 1.0 koa2概览篇
    • 1.1 快速开始
    • 1.2 async await使用
    • 1.3 koa2简析结构
    • 1.4 koa中间件开发与使用
    • 10.1 单元测试
    • 11.1 开发debug
    • 12.1 快速启动
    • 12.2 框架设计
    • 12.3 分层操作
    • 12.4 数据库设计
    • 12.5 路由设计
    • 12.6 webpack4环境搭建
    • 12.7 使用react
    • 12.8 登录注册功能实现
    • 12.9 session登录态判断处理
    • 13.1 import export使用
    • 2.1 原生koa2实现路由
    • 2.2 koa router中间
    • 3.1 GET请求数据获取
    • 3.2 POST请求数据获取
    • 3.3 koa bodyparser中间件
    • 4.1 原生koa2实现静态资源服务器
    • 4.2 koa static中间件
    • 5.1 koa2使用cookie
    • 5.2 koa2实现session
    • 6.1 koa2加载模板引擎
    • 6.2 ejs模板引擎
    • 7.1 busboy模块
    • 7.2 上传文件简单实现
    • 7.3 异步上传图片实现
    • 8.1 mysql模块
    • 8.2 async await封装使用mysql
    • 8.3 项目建表初始化
    • 9.1 原生koa2实现JSONP
    • 9.2 koa jsonp中间件
  • 其他

    • 操作数据库
    • Session 与 Token
    • Cookie、Session、Token、JWT
    • Socket
完整面试题地址:
作者:程序员poetry
扫码关注作者公众号:「前端进阶之旅」 每天分享技术干货
前端进阶之旅公众号二维码

进程相关 process|Nodejs专题系列

# 进程相关 process

30 秒速记

  • process 是全局对象,代表「当前这个 Node 进程」:参数、环境变量、工作目录、输入输出、退出、信号、资源占用都在它上面
  • 退出优先 process.exitCode = 1,让进程自然结束;process.exit() 是硬退出,可能截断还没写完的 stdout
  • uncaughtException / unhandledRejection 只用来记日志然后退出,别吞掉继续跑,交给 PM2、容器去重启
  • 监听了 SIGTERM 就接管了默认退出,清理完要自己退出,还要设个超时兜底
  • 配置在启动时集中从 process.env / process.argv 读一次,业务代码别到处读

process 是 Node.js 里代表当前进程的全局对象,程序和操作系统打交道基本都经过它。 拿参数用 argv,拿配置用 env,读写终端用 stdin / stdout,退出和信号也在这。工程上最容易出问题的是退出:我一般设 process.exitCode 让程序自然退出,而不是到处 process.exit(),后者会直接掐断还没写完的输出。还有部署时容器发 SIGTERM,要监听它做优雅关闭:

process.on('SIGTERM', () => {
  server.close(() => process.exit(0));      // 不再接新请求,处理完存量再退
  setTimeout(() => process.exit(1), 10000).unref(); // 10 秒还没关完就强退
});
@前端进阶之旅: 代码已经复制到剪贴板

理解「进程相关 process」时,要先明确输入、运行阶段和可观察输出。这里的交互实验会分别执行正常路径与失败路径,并把 Node.js 的关键状态变化和同屏代码对应起来;不能只记命令名称。

工程中还要验证退出码、资源清理和异常输入。属于 process 场景的配置应保持最小可复现,并在开发环境与 CI 中使用相同命令复跑,避免把平台差异或隐式默认值带到线上。

process 上的东西多,按用途记会清楚很多:

  • 输入:process.argv(命令行参数)、process.execArgv(Node 自身参数)、process.env(环境变量)、process.stdin。
  • 输出:process.stdout、process.stderr、process.exitCode。
  • 环境:process.cwd()、process.platform、process.version、process.pid。
  • 生命周期:process.exit()、process.on('exit')、process.on('SIGTERM')、process.on('uncaughtException')、process.on('unhandledRejection')。
  • 调度:process.nextTick()。
  • 资源:process.memoryUsage()、process.cpuUsage()、process.uptime()、process.hrtime.bigint()。

有一点常被忽略:exit 事件的回调里只能做同步操作,异步的写日志、发请求不会执行完。要在退出前做异步清理,得在 SIGTERM 或业务结束的地方做,做完再退出。

process.on('exit', (code) => {
  console.log('退出码', code);         // 会打印
  setTimeout(() => console.log('x'), 0); // 永远不会执行
});
process.exitCode = 2;
@前端进阶之旅: 代码已经复制到剪贴板

面试官追问

追问 1命令行工具打印了「完成」,CI 却判它失败,为什么?
参考回答

CI 看的是退出码,不看打印内容。多半是某条路径设了非零 exitCode,或者有未处理的 Promise 拒绝,Node 15 起默认会让进程以非零码退出。echo $? 一看就知道。

追问 2process.exitCode = 1 和 process.exit(1) 有什么区别?
参考回答

前者只是记下退出码,等事件循环空了自然退出,日志、文件写入都能完成;后者立刻退出,挂起的异步操作全丢。脚本里除非确实要马上停,否则用前者。

追问 3代码里加了 process.on('uncaughtException'),打个日志就继续跑,可以吗?
参考回答

不推荐。抛到这里说明某个流程中途崩了,内存里的状态可能已经是乱的,比如锁没释放、连接一半。记完日志就退出,让 PM2 或容器重启一个干净的进程。

追问 4容器发版时总有一批请求报错,和 process 有什么关系?
参考回答

容器停止时先发 SIGTERM,没处理的话进程立刻退出,正在处理的请求就断了。监听 SIGTERM,先 server.close() 停止接新请求,等存量处理完再退,设个超时防止卡死。

追问 5任务报完错一直不退出,可能是什么原因?
参考回答

事件循环里还有东西撑着:没清的 setInterval、没关的数据库连接、没关的 readline。可以用 why-is-node-running 这类工具看是哪个句柄,修好清理逻辑,别靠 process.exit() 硬掐。

# 模块概览

30 秒速记

  • process 是全局对象,不用 require 就能用;require('process') 拿到的是同一个对象
  • 读:命令行参数、环境变量、工作目录、进程 ID、内存占用
  • 写:设环境变量、改工作目录、设退出码、改进程标题
  • 它是进程边界,不是业务全局变量仓库,别往上挂业务状态
  • 配置在启动层集中读一次、校验好,再传给业务模块

process 是 Node.js 的全局对象,用来读写当前进程的信息,不用引入就能直接用。 能读的有命令行参数 argv、环境变量 env、工作目录 cwd()、进程号 pid;能改的有环境变量、工作目录、退出码、进程标题。我的习惯是只在启动入口读 process.env 和 process.argv,整理成一个校验过的 config 对象传下去,业务代码里不直接读,这样测试时换配置很方便,也不会出现十几个地方各自给默认值的情况。

process是node的全局模块,作用比较直观。可以通过它来获得node进程相关的信息,比如运行node程序时的命令行参数。或者设置进程相关信息,比如设置环境变量。

面试官追问

追问 1require('process') 和直接用 process 有区别吗?
参考回答

没区别,拿到的是同一个对象。显式引入的好处是依赖写得清楚,ESM 里也常写 import process from 'node:process'。

追问 2业务模块里到处 process.env.XXX,有什么问题?
参考回答

默认值散落各处,同一个配置不同地方可能给不同的默认值;测试要改环境变量才能换配置。启动时集中读、转类型、校验,导出一个 config 对象,业务只用它。

追问 3把用户会话、缓存挂在 process 上当全局变量用,行不行?
参考回答

别这么干。process 是进程本身的接口,挂上去的东西没有边界、谁都能改,测试也没法隔离。要共享状态就用模块导出的单例。

追问 4服务连到了错误的数据库,代码没报错,怎么用 process 定位?
参考回答

启动时打一行脱敏后的最终配置及来源,比如数据库主机来自 env 还是 argv 覆盖。重点核对 process.env 里实际拿到的值,密码这类字段只打是否存在,不打明文。

# 环境变量:process.env

30 秒速记

  • process.env 是个对象,存当前进程拿到的环境变量,值永远是字符串
  • NODE_ENV=production node env.js 只对这一条命令生效,例子输出应该是「生产环境」
  • 这种 VAR=x cmd 写法 Windows 的 cmd 不认,跨平台用 cross-env
  • 数字、布尔要自己转:process.env.PORT 是 '3000','false' 也是真值
  • 密钥通过环境变量注入可以,但别把整个 process.env 打进日志

process.env 就是当前进程拿到的环境变量,最常见的用法是读 NODE_ENV 判断是不是生产环境。 执行 NODE_ENV=production node env.js,process.env.NODE_ENV 就是 'production',例子会打印「生产环境」。坑主要有三个:值全是字符串,'false' 也是真值,PORT 要 Number() 转;Windows 的 cmd 不认这种前缀写法,团队里有人用 Windows 就上 cross-env;环境变量是启动时继承来的,在终端里 export 不会影响已经跑起来的进程。

const port = Number(process.env.PORT ?? 3000);
const debug = process.env.DEBUG === 'true'; // 别写 Boolean(process.env.DEBUG)
if (Number.isNaN(port)) throw new Error('PORT 必须是数字'); // 启动时就失败
@前端进阶之旅: 代码已经复制到剪贴板

使用频率很高,node服务运行时,时常会判断当前服务运行的环境,如下所示

if(process.env.NODE_ENV === 'production'){
    console.log('生产环境');
}else{
    console.log('非生产环境');
}
@前端进阶之旅: 代码已经复制到剪贴板

运行命令 NODE_ENV=production node env.js,输出如下

非生产环境
@前端进阶之旅: 代码已经复制到剪贴板

面试官追问

追问 1明明执行了 NODE_ENV=production node env.js,打印的却是「非生产环境」,怎么查?
参考回答

先看是不是 Windows 的 cmd,它不认这种写法,变量根本没传进去,用 cross-env NODE_ENV=production node env.js。其次看值有没有多余空格或大小写不对,比如 'production '。

追问 2配置了 DEBUG=false,代码里 if (process.env.DEBUG) 却进了分支,为什么?
参考回答

环境变量全是字符串,'false' 是非空字符串,判断为真。要写成 process.env.DEBUG === 'true'。

追问 3只有 production 和 else 两个分支,加了预发环境有什么风险?
参考回答

预发会落进非生产分支,可能开着调试开关、连着测试服务。NODE_ENV 最好只表达运行模式,部署环境另起一个变量比如 APP_ENV,对未知值直接启动失败。

追问 4在服务器终端 export NODE_ENV=production,再看已经在跑的服务,为什么没变?
参考回答

环境变量是进程启动时从父进程复制的,之后外面改了不影响它。要在 PM2 配置、Dockerfile 或 systemd 里配好再重启服务。

追问 5排查时想把整个 process.env 打到日志里,可以吗?
参考回答

不行,里面有数据库密码、token。只打白名单里的非敏感字段,敏感字段打「已设置 / 未设置」。

# 异步:process.nextTick(fn)

← 6.2 逐行读取 readline7.2 子进程 child →

fe